import chain.*;
import command.*;
import data.*;
import factory.*;
import machine.AgriculturalMachine;
import observer.EnvironmentSensor;

import java.util.*;


public class Main {

    private static final Scanner scanner = new Scanner(System.in);
    private static final List<AgriculturalMachine> machines = new ArrayList<>();
    private static final Random random = new Random(); // 用于生成随机土壤数据
    private static final PathPlanner pathPlanner = new PathPlanner(); // 路径规划器
    public static void main(String[] args) {
        initializeMachines();
        showMainMenu();
    }

    private static void initializeMachines() {
        AgriculturalMachineFactory tractorFactory = new TractorFactory();
        AgriculturalMachineFactory harvesterFactory = new HarvesterFactory();
        AgriculturalMachineFactory seederFactory = new SeederFactory();

        machines.add(tractorFactory.createMachine("TR-001"));
        machines.add(harvesterFactory.createMachine("HV-002"));
        machines.add(seederFactory.createMachine("SD-003"));
    }

    private static void showMainMenu() {
        while (true) {
            printMenu();
            int choice = getValidInput(0, 5);
            handleChoice(choice);
        }
    }

    private static void printMenu() {
        System.out.println("\n## 智能农机管理系统");
        System.out.println("1. 农机设备管理");
        System.out.println("2. 环境监测");
        System.out.println("3. 路径规划");
        System.out.println("4. 任务执行");
        System.out.println("5. 系统管理");
        System.out.println("0. 退出系统");
        System.out.print("\n请选择功能（0-5）：");
    }

    private static int getValidInput(int min, int max) {
        while (true) {
            try {
                int input = Integer.parseInt(scanner.nextLine());
                if (input >= min && input <= max) {
                    return input;
                }
                System.out.printf("输入错误，请输入%d-%d之间的数字：", min, max);
            } catch (NumberFormatException e) {
                System.out.printf("无效输入，请输入数字（%d-%d）：", min, max);
            }
        }
    }

    private static void handleChoice(int choice) {
        switch (choice) {
            case 1:
                handleMachineManagement();
                break;
            case 2:
                handleEnvironmentMonitoring();
                break;
            case 3:
                handlePathPlanning();
                break;
            case 4:
                handleTaskExecution();
                break;
            case 5:
                handleSystemManagement();
                break;
            case 0:
                exitSystem();
                break;
            default:
                System.out.println("无效选项");
        }
    }
    // 工厂方法模式应用
    private static void handleMachineManagement() {
        while (true) {
            System.out.println("\n--- 农机设备管理 ---");
            System.out.println("1. 查看设备列表");
            System.out.println("2. 设备状态监控");
            System.out.println("3. 任务分配与调度");
            System.out.println("4. 添加新设备");
            System.out.println("0. 返回主菜单");
            System.out.print("请选择操作（0-4）：");

            int choice = getValidInput(0, 4);

            switch (choice) {
                case 1:
                    displayMachineList();
                    break;
                case 2:
                    monitorMachineStatus();
                    break;
                case 3:
                    assignTasks();
                    break;
                case 4:
                    addNewMachine();
                    break;
                case 0:
                    return;
            }
        }
    }
    // 显示设备列表
    private static void displayMachineList() {
        System.out.println("\n设备列表：");
        System.out.println("========================================================================");
        System.out.println("| 序号 | 设备类型 | 设备编号 | 位置     | 状态     | 油量 | 当前任务   |");
        System.out.println("========================================================================");

        for (int i = 0; i < machines.size(); i++) {
            AgriculturalMachine machine = machines.get(i);
            MachineStatus status = machine.getStatus();
            System.out.printf("| %-4d | %-8s | %-8s | %-8s | %-8s | %3d%% | %-10s |\n",
                    i + 1,
                    machine.getType(),
                    machine.getMachineId(),
                    status.getPosition(),
                    status.getState(),
                    status.getFuelLevel(),
                    status.getCurrentTask());
        }
        System.out.println("========================================================================");
        pressAnyKey();
    }

    // 设备状态监控
    private static void monitorMachineStatus() {
        System.out.println("\n设备状态监控：");
        System.out.println("----------------------------------------------");
        for (AgriculturalMachine machine : machines) {
            MachineStatus status = machine.getStatus();
            System.out.println("设备: " + machine.getMachineId() + " (" + machine.getType() + ")");
            System.out.println("  位置: " + status.getPosition());
            System.out.println("  状态: " + status.getState());
            System.out.println("  油量: " + status.getFuelLevel() + "%");
            System.out.println("  任务: " + status.getCurrentTask());
            System.out.println("  工作时间: " + status.getWorkingHours() + "小时");
            System.out.println("  维护状态: " + status.getMaintenanceStatus());
            System.out.println("----------------------------------------------");
        }
        pressAnyKey();
    }

    // 任务分配
    private static void assignTasks() {
        System.out.println("\n任务分配与调度：");
        System.out.println("可用设备:");
        for (int i = 0; i < machines.size(); i++) {
            AgriculturalMachine machine = machines.get(i);
            MachineStatus status = machine.getStatus();
            if (status.getState().equals("空闲")) {
                System.out.println((i + 1) + ". " + machine.getType() + " (" + machine.getMachineId() + ")");
            }
        }

        System.out.print("请选择设备序号：");
        int machineIndex = getValidInput(1, machines.size()) - 1;
        AgriculturalMachine selectedMachine = machines.get(machineIndex);

        System.out.println("可选任务类型：");
        System.out.println("1. 播种任务");
        System.out.println("2. 收割任务");
        System.out.println("3. 喷洒任务");
        System.out.println("4. 耕地任务");
        System.out.print("请选择任务类型：");
        int taskType = getValidInput(1, 4);

        System.out.print("请输入任务区域：");
        String area = scanner.nextLine();

        // 分配任务
        String taskName = "";
        switch (taskType) {
            case 1: taskName = "播种-" + area; break;
            case 2: taskName = "收割-" + area; break;
            case 3: taskName = "喷洒-" + area; break;
            case 4: taskName = "耕地-" + area; break;
        }

        selectedMachine.assignTask(taskName);
        System.out.println("已为设备 " + selectedMachine.getMachineId() + " 分配任务: " + taskName);
        pressAnyKey();
    }

    // 添加新设备
    private static void addNewMachine() {
        System.out.println("\n添加新设备：");
        System.out.println("1. 拖拉机");
        System.out.println("2. 收割机");
        System.out.println("3. 播种机");
        System.out.println("4. 喷洒机");
        System.out.print("请选择设备类型：");
        int typeChoice = getValidInput(1, 4);

        System.out.print("请输入设备编号：");
        String machineId = scanner.nextLine();

        AgriculturalMachineFactory factory = null;
        switch (typeChoice) {
            case 1: factory = new TractorFactory(); break;
            case 2: factory = new HarvesterFactory(); break;
            case 3: factory = new SeederFactory(); break;
            case 4: factory = new SprayerFactory(); break;
        }

        AgriculturalMachine newMachine = factory.createMachine(machineId);
        machines.add(newMachine);
        System.out.println("成功添加新设备: " + newMachine.getType() + " (" + machineId + ")");
        pressAnyKey();
    }


    // 环境监测功能 - 采集并展示土壤数据
    private static void handleEnvironmentMonitoring() {
        System.out.println("\n--- 环境监测 ---");
        System.out.println("正在采集土壤数据...");

        // 创建环境传感器
        EnvironmentSensor sensor = new EnvironmentSensor();

        // 模拟采集3个不同位置的土壤数据
        SoilData location1 = sensor.collectSoilData("A区");
        SoilData location2 = sensor.collectSoilData("B区");
        SoilData location3 = sensor.collectSoilData("C区");

        // 显示采集结果
        System.out.println("\n土壤数据采集结果：");
        System.out.println("--------------------------------------");
        System.out.println("| 位置 | 湿度(%) | pH值 | 氮含量 | 磷含量 | 钾含量 |");
        System.out.println("--------------------------------------");
        System.out.println(location1);
        System.out.println(location2);
        System.out.println(location3);
        System.out.println("--------------------------------------");

        // 评估土壤状况
        System.out.println("\n土壤状况评估：");
        System.out.println("A区: " + evaluateSoilCondition(location1));
        System.out.println("B区: " + evaluateSoilCondition(location2));
        System.out.println("C区: " + evaluateSoilCondition(location3));

        pressAnyKey();
    }
    public static void handlePathPlanning() {
        System.out.println("\n--- 路径规划 ---");

        // 1. 动态路径计算
        System.out.println("\n1. 基于农田状况的动态路径计算");
        FieldMap fieldMap = new FieldMap(5, 5); // 创建5x5农田地图
        fieldMap.generateRandomConditions();    // 随机生成农田状况
        fieldMap.displayMap();

        // 2. 避障与紧急路径重规划
        System.out.println("\n2. 避障与紧急路径重规划");
        Path originalPath = pathPlanner.calculatePath(fieldMap, "A1", "E5");
        System.out.println("原始路径: " + originalPath);

        // 模拟突发障碍物
        fieldMap.addObstacle(2, 3);
        System.out.println("\n检测到障碍物! 位置: C4");

        Path replannedPath = pathPlanner.replanPath(fieldMap, originalPath);
        System.out.println("重新规划路径: " + replannedPath);

        // 3. 多农机协同路径优化
        System.out.println("\n3. 多农机协同路径优化");
        List<AgriculturalMachine> activeMachines = Arrays.asList(
                machines.get(0), // 拖拉机
                machines.get(1)  // 收割机
        );

        MultiMachineScheduler scheduler = new MultiMachineScheduler(fieldMap);
        scheduler.assignTasks(activeMachines);
        scheduler.displaySchedule();

        pressAnyKey();
    }
    // 评估土壤状况
    private static String evaluateSoilCondition(SoilData data) {
        if (data.getMoisture() < 30) return "干旱，需要灌溉";
        if (data.getMoisture() > 70) return "过湿，需排水";
        if (data.getPh() < 5.5) return "酸性过高，需添加石灰";
        if (data.getPh() > 7.5) return "碱性过高，需添加硫磺";
        return "土壤状况良好";
    }

    private static void handleSystemManagement() {
        System.out.println("\n--- 异常事件处理 ---");
        manageUserPermissions();
    }

    private static void exitSystem() {
        System.out.println("\n系统正在安全关闭...");
        System.exit(0);
    }

    private static void pressAnyKey() {
        System.out.print("\n按回车键返回主菜单...");
        scanner.nextLine();
        scanner.nextLine();
    }

    // 用户权限管理
    private static void manageUserPermissions() {
        System.out.println("\n--- 用户权限管理 ---");
        UserPermissionManager manager = new UserPermissionManager();

        System.out.println("当前用户权限:");
        System.out.println("----------------------------------");
        System.out.println("| 用户名       | 角色        | 权限          |");
        System.out.println("----------------------------------");
        System.out.println("| admin       | 系统管理员  | 所有权限      |");
        System.out.println("| operator1   | 操作员      | 设备控制      |");
        System.out.println("| monitor1    | 监控员      | 只读权限      |");
        System.out.println("----------------------------------");

        System.out.println("\n1. 添加用户");
        System.out.println("2. 修改权限");
        System.out.println("3. 删除用户");
        System.out.print("请选择操作（1-3，0返回）：");

        int choice = getValidInput(0, 3);
        switch (choice) {
            case 1:
                System.out.println("执行添加用户操作...");
                break;
            case 2:
                System.out.println("执行修改权限操作...");
                break;
            case 3:
                System.out.println("执行删除用户操作...");
                break;
        }

        pressAnyKey();
    }


    private static void handleTaskExecution() {
        while (true) {
            System.out.println("\n--- 任务执行 ---");
            System.out.println("1. 创建新任务");
            System.out.println("2. 执行任务队列");
            System.out.println("3. 查看任务历史");
            System.out.println("4. 取消待执行任务");
            System.out.println("0. 返回主菜单");
            System.out.print("请选择操作（0-4）：");

            int choice = getValidInput(0, 4);

            switch (choice) {
                case 1:
                    createNewTask();
                    break;
                case 2:
                    executeTaskQueue();
                    break;
                case 3:
                    viewTaskHistory();
                    break;
                case 4:
                    cancelPendingTasks();
                    break;
                case 0:
                    return;
            }
        }
    }
    // 创建新任务
    private static void createNewTask() {
        System.out.println("\n--- 创建新任务 ---");

        // 选择设备
        System.out.println("选择设备:");
        for (int i = 0; i < machines.size(); i++) {
            System.out.println((i + 1) + ". " + machines.get(i).getMachineId() +
                    " (" + machines.get(i).getType() + ")");
        }
        System.out.print("请选择设备序号: ");
        int machineIndex = getValidInput(1, machines.size()) - 1;
        AgriculturalMachine machine = machines.get(machineIndex);

        // 选择操作类型
        System.out.println("\n选择操作类型:");
        System.out.println("1. 启动设备");
        System.out.println("2. 停止设备");
        System.out.print("请选择操作类型: ");
        int operationType = getValidInput(1, 4);

        Command command = null;
        switch (operationType) {
            case 1:
                command = new StartMachineCommand((AgriculturalMachine) machine);
                TaskManager.executeAll();
                break;
            case 2:
                command = new StopMachineCommand((AgriculturalMachine) machine);
                break;
        }

        if (command != null) {
            TaskManager.addTask(command);
        }
        pressAnyKey();
    }

    // 执行任务队列
    private static void executeTaskQueue() {
        System.out.println("\n--- 执行任务队列 ---");
        TaskManager.displayPendingTasks();
        System.out.println("\n1. 执行所有任务");
        System.out.println("2. 撤销上一步");
        System.out.println("3. 重做上一步");
        System.out.println("0. 返回");
        System.out.print("请选择操作: ");

        int choice = getValidInput(0, 3);
        switch (choice) {
            case 1:
                TaskManager.executeAll();
                break;
            case 2:
                TaskManager.undoLast();
                System.out.println("已撤销上一步操作");
                break;
            case 3:
                TaskManager.redoLast();
                System.out.println("已重做上一步操作");
                break;
        }
        pressAnyKey();
    }

    // 查看任务历史
    private static void viewTaskHistory() {
        System.out.println("\n--- 任务历史 ---");
        TaskManager.displayExecutedTasks();
        pressAnyKey();
    }

    // 取消待执行任务
    private static void cancelPendingTasks() {
        System.out.println("\n--- 取消待执行任务 ---");
        TaskManager.displayPendingTasks();
        System.out.print("\n确定要取消所有待执行任务吗？(Y/N): ");
        String confirm = scanner.nextLine();
        if (confirm.equalsIgnoreCase("Y")) {
            TaskManager.cancelPendingTasks();
        }
        pressAnyKey();
    }

}